home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1999 / MacHack 1999.toast / The Hacks / X-Ray / X-Ray INIT Source / apps.c next >
Encoding:
Text File  |  1999-06-09  |  9.1 KB  |  350 lines  |  [TEXT/CWIE]

  1. // Copyright (C) 1999 Eric Roccasecca.  All rights reserved.
  2.  
  3. #include "X_Ray_Priv.h"
  4.  
  5.  
  6. X_Ray_AppRecHandle RememberApp (void)
  7. {
  8.     X_Ray_AppRecHandle        curApp, newApp;
  9.     ProcessSerialNumber        curSerialNum;
  10.     OSErr                    err;
  11.     ProcessInfoRec            info;
  12.     
  13.     // first go see if app already exists in chain just to be safe
  14.     curApp = GetCurrentAppRec();
  15.     if (curApp) // this app is already in the list, don't bother remembering it again
  16.         return nil;
  17.     
  18.     err = GetCurrentProcess (&curSerialNum);
  19.     
  20.     // find end of app list
  21.     if (gCommRec.appList)
  22.     {
  23.         curApp = gCommRec.appList;
  24.         while ((*curApp)->nextApp) // walk to end of app list
  25.             curApp = (*curApp)->nextApp;
  26.     }
  27.     else
  28.         curApp = nil;
  29.     
  30.     newApp = (X_Ray_AppRecHandle)NewHandleSysClear (sizeof(X_Ray_AppRec));    // create new appRec in system heap
  31.     if (newApp)
  32.     {
  33.         info.processInfoLength = sizeof(ProcessInfoRec);
  34.         info.processName = (*newApp)->name;
  35.         info.processAppSpec = nil;
  36.         err = GetProcessInformation (&curSerialNum, &info);
  37.         
  38.         (*newApp)->appSerialNum = curSerialNum;
  39.         (*newApp)->mode = info.processMode;
  40.         (*newApp)->previousApp = curApp;
  41.         if (curApp)
  42.             (*curApp)->nextApp = newApp; // append to end of app list
  43.         else
  44.             gCommRec.appList = newApp; // no apps, so start new list
  45.         return newApp;
  46.     }
  47.     
  48.     return nil;
  49. }
  50.  
  51.  
  52. void ForgetApp (void)
  53. {
  54.     X_Ray_AppRecHandle        curApp, deletedApp;
  55.     ProcessSerialNumber        curPSN;
  56.     OSErr                    err;
  57.     Boolean                    sameApp;
  58.     
  59.     GetCurrentProcess (&curPSN);
  60.     
  61.     curApp = gCommRec.appList;
  62.     while (curApp != nil)
  63.     {
  64.         err = SameProcess (&(*curApp)->appSerialNum, &curPSN, &sameApp);
  65.         if (sameApp)
  66.         {
  67.             deletedApp = curApp;
  68.             
  69.             // fix app list
  70.             if ((*deletedApp)->nextApp)
  71.                 (*(*deletedApp)->nextApp)->previousApp = (*deletedApp)->previousApp;
  72.             if ((*deletedApp)->previousApp)
  73.                 (*(*deletedApp)->previousApp)->nextApp = (*deletedApp)->nextApp;
  74.             
  75.             if (deletedApp == gCommRec.appList)
  76.                 gCommRec.appList = (*deletedApp)->nextApp;
  77.             
  78.             curApp = (*deletedApp)->nextApp;
  79.             
  80.             PurgeDeadAppWindows (deletedApp);
  81.             
  82.             DisposeHandle ((Handle)deletedApp);
  83.             
  84.             return;
  85.         }
  86.         else
  87.             curApp = (*curApp)->nextApp;
  88.     }
  89. }
  90.  
  91.  
  92. // see if an app has already called InitWindows
  93. // apps shouldn't call InitWindows more than once, but this is just to be safe
  94. Boolean AppInitWindowsState (void)
  95. {
  96.     X_Ray_AppRecHandle        curApp;
  97.     
  98.     curApp = GetCurrentAppRec();
  99.     if (!curApp)
  100.         return false;    // no app rec found, oops!
  101.     
  102.     if ((*curApp)->appWindowsAreInited)
  103.         return false;    // app is already InitWindowed so don't bother doing InitWindow handling
  104.     else
  105.     {
  106.         (*curApp)->appWindowsAreInited = true;
  107.         return true;    // app is not InitWindowed so do the handling
  108.     }
  109. }
  110.  
  111.  
  112. X_Ray_AppRecHandle GetCurrentAppRec (void)
  113. {
  114.     ProcessSerialNumber        curSerialNum;
  115.     X_Ray_AppRecHandle        curApp;
  116.     OSErr                    err;
  117.     Boolean                    sameProcess;
  118.     
  119.     CleanAppList();
  120.     err = GetCurrentProcess (&curSerialNum);
  121.     curApp = gCommRec.appList;
  122.     while (curApp != nil)
  123.     {
  124.         HLock ((Handle)curApp);
  125.         err = SameProcess (&curSerialNum, &(*curApp)->appSerialNum, &sameProcess);
  126.         HUnlock ((Handle)curApp);
  127.         
  128.         if (sameProcess)
  129.             return curApp;
  130.         curApp = (*curApp)->nextApp;
  131.     }
  132.     
  133.     return nil;
  134. }
  135.  
  136.  
  137. // walk app list to get original trap values 
  138. UniversalProcPtr GetLocalTrap (long trapNum)
  139. {
  140.     X_Ray_AppRecHandle        curApp;
  141.     
  142.     curApp = GetCurrentAppRec();
  143.     if (curApp)
  144.     {
  145.         switch (trapNum)
  146.         {
  147.             case _InitWindows:
  148.                 return (*curApp)->appInitWindows;
  149.                 break;
  150.             default:
  151.                 break;
  152.         }
  153.     }
  154.     
  155.     return nil;
  156. }
  157.  
  158.  
  159. // walk app list to get appRec for remembering global window
  160. void SetAppGlobalWindow (WindowPtr theAppGWindow)
  161. {
  162.     X_Ray_AppRecHandle        curApp;
  163.     
  164.     curApp = GetCurrentAppRec();
  165.     if (curApp)
  166.     {
  167.         if ((*curApp)->appGlobalWindow == nil)
  168.             (*curApp)->appGlobalWindow = (LayerPtr)theAppGWindow;
  169.         // JUST CHANGED
  170.         else
  171.             curApp = (*curApp)->nextApp;
  172.     }
  173. }
  174.  
  175.  
  176. // removes expired apps from app list and their associated windows
  177. // this may not be needed because of the patch of CleanupApplication()
  178. // but I just can't bring myself to remove this yet
  179. void CleanAppList()
  180. {
  181.     X_Ray_AppRecHandle        curApp, deletedApp;
  182.     ProcessInfoRec            info;
  183.     OSErr                    err;
  184.     
  185.     curApp = gCommRec.appList;
  186.     while (curApp != nil)
  187.     {
  188.         info.processInfoLength = sizeof(ProcessInfoRec);
  189.         info.processName = nil;
  190.         info.processAppSpec = nil;
  191.         err = GetProcessInformation (&(*curApp)->appSerialNum, &info);
  192.         
  193.         if (err == procNotFound)
  194.         {
  195.             deletedApp = curApp;
  196.             
  197.             // fix app list
  198.             if ((*deletedApp)->nextApp)
  199.                 (*(*deletedApp)->nextApp)->previousApp = (*deletedApp)->previousApp;
  200.             if ((*deletedApp)->previousApp)
  201.                 (*(*deletedApp)->previousApp)->nextApp = (*deletedApp)->nextApp;
  202.             
  203.             if (deletedApp == gCommRec.appList)
  204.                 gCommRec.appList = (*deletedApp)->nextApp;
  205.             
  206.             curApp = (*deletedApp)->nextApp;
  207.             
  208.             PurgeDeadAppWindows (deletedApp);
  209.             
  210.             DisposeHandle ((Handle)deletedApp);
  211.         }
  212.         else
  213.             curApp = (*curApp)->nextApp;
  214.     }
  215. }
  216.  
  217.  
  218. // removes transparent or clear windows belonging to an app that has died and didn't clean up after itself
  219. void PurgeDeadAppWindows (X_Ray_AppRecHandle deletedApp)
  220. {
  221.     X_Ray_WindowHandle        deadWin;
  222.     
  223.     deadWin = gCommRec.tsmWindowList; // check the TSM list for app owned window
  224.     while (deadWin)
  225.     {
  226.         if ((*deadWin)->owner == deletedApp)
  227.             X_Ray_DisposeWindow (deadWin);
  228.         deadWin = (*deletedApp)->windowList;
  229.     }
  230.     
  231.     // this may be removed if applications have to take responsibility for providing enough memory for transparent windows
  232.     // for now though X-Ray manages this memory itself
  233.     deadWin = (*deletedApp)->windowList;
  234.     while (deadWin)
  235.     {
  236.         X_Ray_DisposeWindow (deadWin);
  237.         deadWin = (*deletedApp)->windowList;
  238.     }
  239. }
  240.  
  241.  
  242. // reorders an app in the app list
  243. RgnHandle ReorderApp (X_Ray_AppRecHandle theApp, short reorderMethod)
  244. {
  245.     X_Ray_AppRecHandle        curApp;
  246.     RgnHandle                updateRgn = nil, curVisRgn = nil;
  247.     X_Ray_WindowHandle        curTransWindow;
  248.     GrafPtr                    origPort;
  249.     WindowPtr                curWindow;
  250.     
  251.     curApp = gCommRec.appList;
  252.     switch (reorderMethod) {
  253.         case kROMethod_BringToFront:
  254.             if (theApp == curApp) // app is already front most
  255.                 break;
  256.             
  257.             updateRgn = NewRgn();
  258.             curVisRgn = NewRgn();
  259.             
  260.             GetPort (&origPort);
  261.             curTransWindow = (*curApp)->windowList;
  262.             while (curTransWindow)
  263.             {
  264.                 // accumulate a region of all transwind visRgns
  265.                 CopyRgn ((*curTransWindow)->theWindow->visRgn, curVisRgn);
  266.                 SetPort ((*curTransWindow)->theWindow); // to get proper coordinate system
  267.                 X_Ray_LocalToGlobalRgn (curVisRgn);
  268.                 UnionRgn (updateRgn, curVisRgn, updateRgn);
  269.                 
  270.                 curTransWindow = (*curTransWindow)->nextWindow;
  271.             }
  272.             
  273.             // see where accumulated visRgns intersect the app comming forward
  274.             // and invalidate the intersections
  275.             if (!EmptyRgn (updateRgn))
  276.             {
  277.                 curWindow = GetFirstLayerWindow ((LayerPtr)(*theApp)->appGlobalWindow);
  278.                 while (curWindow)
  279.                 {
  280.                     SetPort (curWindow); // to get proper coordinate system
  281.                     X_Ray_GlobalToLocalRgn (updateRgn);
  282.                     SectRgn (curWindow->visRgn, updateRgn, curVisRgn);
  283.                     if (!EmptyRgn (curVisRgn))
  284.                         InvalRgn (curVisRgn);
  285.                     X_Ray_LocalToGlobalRgn (updateRgn);
  286.                     
  287.                     curWindow = (WindowPtr)((WindowPeek)curWindow)->nextWindow;
  288.                 }
  289.                 SetPort (origPort);
  290.             }
  291.             
  292.             if ((*theApp)->nextApp)
  293.                 (*(*theApp)->nextApp)->previousApp = (*theApp)->previousApp;
  294.             if ((*theApp)->previousApp)
  295.                 (*(*theApp)->previousApp)->nextApp = (*theApp)->nextApp;
  296.             if (gCommRec.appList)
  297.                 (*(gCommRec.appList))->previousApp = theApp;
  298.             (*theApp)->nextApp = gCommRec.appList;
  299.             (*theApp)->previousApp = nil;
  300.             gCommRec.appList = theApp;
  301.             
  302.             DisposeRgn (curVisRgn);
  303.             
  304.             //DebugStr ("\pnew front app…");
  305.             //DebugStr ((*theApp)->name);
  306.             break;
  307.         
  308. // I commented this out because this is actually handled when the app beind the hiding app is brought to the foreground
  309. // Once again, I just can't bring myself to delete this code yet
  310. /*        case kROMethod_ShowHide:
  311.             if (switchWindow == (*theApp)->appGlobalWindow) // no need to move an app behind itself, this will probably never occur
  312.                 break;
  313.             
  314.             while (true)
  315.             {
  316.                 curTransWindow = X_Ray_GetWindowRec (curWindow);
  317.                 if (curTransWindow) // remember most recently found transparent window in front to back order
  318.                     foundWindow = curTransWindow;
  319.                 if (curWindow == switchWindow) // found the window to go behind, can be nil which means window is being moved to the end of list
  320.                 {
  321.                     if ((foundWindow != theApp) && ((*foundWindow)->nextWindow != theApp) && (foundWindow != nil)) // don't operate on the same window of course
  322.                     {
  323.                         if (((*theApp)->windowKind&kTSMWindow) && (gCommRec.tsmWindowList == theApp)) // update list heads if necessary
  324.                             gCommRec.tsmWindowList = (*foundWindow)->nextWindow;
  325.                         else if ((*((*theApp)->owner))->windowList == theApp)
  326.                             (*((*theApp)->owner))->windowList = (*theApp)->nextWindow;
  327.                         
  328.                         if ((*theApp)->nextWindow)
  329.                             (*(*theApp)->nextWindow)->previousWindow = (*theApp)->previousWindow;
  330.                         (*theApp)->nextWindow = (*foundWindow)->nextWindow;
  331.                         if ((*theApp)->nextWindow)
  332.                             (*(*theApp)->nextWindow)->previousWindow = theApp;
  333.                         (*foundWindow)->nextWindow = theApp;
  334.                         (*theApp)->previousWindow = foundWindow;
  335.                     }
  336.                     break;
  337.                 }
  338.                 if (curWindow == nil) // end of chain reached
  339.                     break;
  340.                 curWindow = (WindowPtr)((WindowPeek)curWindow)->nextWindow;
  341.             }
  342.             break;
  343. */        
  344.         default:
  345.             break;
  346.     }
  347.     
  348.     return updateRgn;
  349. }
  350.